﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.ComponentModel;
using System.Collections;

namespace UCS.XNA.Utils
{
    public class RefreshableCollection<T> : INotifyCollectionChanged, IList<T>
    {
        private List<T> _addPendingList;
        private List<T> _removePendingList;
        private ObservableCollection<T> _list;

        public RefreshableCollection()
        {
            this._list = new ObservableCollection<T>();
            this._addPendingList = new List<T>();
            this._removePendingList = new List<T>();
        }

        public void Refresh()
        {
            this.RemovePendingItems();
            this.AddPendingItems();
        }

        private void AddPendingItems()
        {
            List<T> addedItems = new List<T>();

            foreach (var item in this._addPendingList)
            {
                this._list.Add(item);
                addedItems.Add(item);
            }

            this._addPendingList.Clear();

            if (this.CollectionChanged != null && addedItems.Count > 0)
                this.CollectionChanged(this, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, addedItems));
        }

        private void RemovePendingItems()
        {
            List<T> removedItems = new List<T>();

            foreach (var item in this._removePendingList)
            {
                this._list.Remove(item);
                removedItems.Add(item);
            }

            this._removePendingList.Clear();

            if (this.CollectionChanged != null && removedItems.Count > 0)
                this.CollectionChanged(this, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove, removedItems));
        }

        public event NotifyCollectionChangedEventHandler CollectionChanged;

        public IEnumerator<T> GetEnumerator()
        {
            return this._list.GetEnumerator();
        }

        IEnumerator IEnumerable.GetEnumerator()
        {
            throw new NotImplementedException();
        }

        public int IndexOf(T item)
        {
            return this._list.IndexOf(item);
        }

        public void Insert(int index, T item)
        {
            throw new NotImplementedException();
        }

        public void RemoveAt(int index)
        {
            this._list.RemoveAt(index);
        }

        public T this[int index]
        {
            get
            {
                return this._list[index];
            }
            set
            {
                this._list[index] = value;
            }
        }

        public void Add(T item)
        {
            this._addPendingList.Add(item);
        }

        public void Clear()
        {
            this._list.Clear();
            this._addPendingList.Clear();
            this._removePendingList.Clear();
        }

        public bool Contains(T item)
        {
            return this._list.Contains(item);
        }

        public void CopyTo(T[] array, int arrayIndex)
        {
            this._list.CopyTo(array, arrayIndex);
        }

        public int Count
        {
            get { return this._list.Count; }
        }

        public bool IsReadOnly
        {
            get { throw new NotImplementedException(); }
        }

        public bool Remove(T item)
        {
            this._removePendingList.Add(item);

            return true;
        }
    }
}
